home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / tsipp / tsipp.lha / tsipp3.0a / src / tSippPoly.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-02  |  13.2 KB  |  401 lines

  1. /*
  2.  *=============================================================================
  3.  *                                  tSippPoly.c
  4.  *-----------------------------------------------------------------------------
  5.  * Tcl commands to manage SIPP polygons and surfaces.
  6.  *-----------------------------------------------------------------------------
  7.  * Copyright 1992 Mark Diekhans
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that the above copyright notice appear in all copies.  Mark Diekhans makes
  11.  * no representations about the suitability of this software for any purpose.
  12.  * It is provided "as is" without express or implied warranty.
  13.  *-----------------------------------------------------------------------------
  14.  * $Id: tSippPoly.c,v 2.0 1992/11/02 03:56:30 markd Rel $
  15.  *=============================================================================
  16.  */
  17.  
  18. #include "tSippInt.h"
  19. #include "primitives.h"
  20.  
  21. /*
  22.  * Internal prototypes.
  23.  */
  24. static void
  25. BindSurfaceToHandle _ANSI_ARGS_((tSippGlob_pt    tSippGlobPtr,
  26.                                  Surface         *surfacePtr));
  27.  
  28. static bool
  29. PushVertexList _ANSI_ARGS_((tSippGlob_pt    tSippGlobPtr,
  30.                             bool            textures,
  31.                             char           *vertexList));
  32.  
  33. static bool
  34. PushVertexArgList _ANSI_ARGS_((tSippGlob_pt    tSippGlobPtr,
  35.                                int             argc,    
  36.                                char          **argv));
  37. /*=============================================================================
  38.  * BindSurfaceToHandle --
  39.  *   Assigns a handle to the specified surface.
  40.  * Parameters:
  41.  *   o tSippGlobPtr (I) - Pointer to the Tcl SIPP globals. The handle is
  42.  *     returned in interp->result.
  43.  *   o surfacePtr (I) - A pointer to the surface.
  44.  *-----------------------------------------------------------------------------
  45.  */
  46. static void
  47. BindSurfaceToHandle (tSippGlobPtr, surfacePtr)
  48.     tSippGlob_pt    tSippGlobPtr;
  49.     Surface         *surfacePtr;
  50. {
  51.     Surface  **surfaceEntryPtr;
  52.  
  53.     surfaceEntryPtr = (Surface **)
  54.         Tcl_HandleAlloc (tSippGlobPtr->surfaceTblPtr, 
  55.                          tSippGlobPtr->interp->result);
  56.     *surfaceEntryPtr = surfacePtr;
  57.     surfacePtr->ref_count++;
  58.  
  59. } /* BindSurfaceToHandle */
  60.  
  61. /*=============================================================================
  62.  * TSippSurfaceHandleToPtr --
  63.  *   Utility procedure to convert a surface handle to a surface pointer.
  64.  *   For use of by functions outside of this module.
  65.  * Parameters:
  66.  *   o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
  67.  *   o handle (I) - A surface handle.
  68.  * Returns:
  69.  *   A pointer to the surface, or NULL if an error occured.
  70.  *-----------------------------------------------------------------------------
  71.  */
  72. Surface *
  73. TSippSurfaceHandleToPtr (tSippGlobPtr, handle)
  74.     tSippGlob_pt    tSippGlobPtr;
  75.     char           *handle;
  76. {
  77.     Surface **surfaceEntryPtr;
  78.  
  79.     surfaceEntryPtr = (Surface **)
  80.         Tcl_HandleXlate (tSippGlobPtr->interp, 
  81.                          tSippGlobPtr->surfaceTblPtr, handle);
  82.     if (surfaceEntryPtr == NULL)
  83.         return NULL;
  84.     return *surfaceEntryPtr;
  85.  
  86. } /* TSippSurfaceHandleToPtr */
  87.  
  88. /*=============================================================================
  89.  * PushVertexList --
  90.  *   Parse, convert a list of vertex coordinates, and optional texture
  91.  * coordinates on the vertex stack.
  92.  * Parameters:
  93.  *   o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
  94.  *   o textures (I) - TRUE if texture coordinates are includes, FALSE if not.
  95.  *   o vertexList (I) - A list of lists of vertex coordinates or vertex and
  96.  *     texture coordinates pairs.
  97.  * Returns:
  98.  *   TRUE if the list and numbers are valid, FALSE if there is an error.
  99.  *-----------------------------------------------------------------------------
  100.  */
  101. static bool
  102. PushVertexList (tSippGlobPtr, textures, vertexList)
  103.     tSippGlob_pt    tSippGlobPtr;
  104.     bool            textures;
  105.     char           *vertexList;
  106. {
  107.     int      vertexArgc, idx;
  108.     char   **vertexArgv;
  109.     Vector   vertex, textureCoord;
  110.  
  111.     if (Tcl_SplitList (tSippGlobPtr->interp, vertexList, &vertexArgc,
  112.                        &vertexArgv) != TCL_OK)
  113.         return FALSE;
  114.     if (textures) {
  115.         for (idx = 0; idx < vertexArgc; idx ++) {
  116.             if (!TSippConvertVertexTex (tSippGlobPtr, vertexArgv [idx],
  117.                                         &vertex, &textureCoord))
  118.                 goto errorExit;
  119.             vertex_tx_push (vertex.x, vertex.y, vertex.z, 
  120.                             textureCoord.x, textureCoord.y, textureCoord.z);
  121.         }
  122.     } else {
  123.         for (idx = 0; idx < vertexArgc; idx ++) {
  124.             if (!TSippConvertVertex (tSippGlobPtr, vertexArgv [idx], &vertex))
  125.                 goto errorExit;
  126.             vertex_push (vertex.x, vertex.y, vertex.z);
  127.         }
  128.     }
  129.  
  130.     ckfree (vertexArgv);
  131.     return TRUE;
  132. errorExit:
  133.     ckfree (vertexArgv);
  134.     return FALSE;
  135.  
  136. } /* PushVertexList */
  137.  
  138. /*=============================================================================
  139.  * PushVertexArgList --
  140.  *   Handles parsing and processing arguments in the form:
  141.  *     [-tex] [vertexList]
  142.  * Parameters:
  143.  *   o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
  144.  *   o argc, argv (I) - Command arguments.
  145.  * Returns:
  146.  *   TRUE if all is ok, FALSE if there is an error.
  147.  *-----------------------------------------------------------------------------
  148.  */
  149. static bool
  150. PushVertexArgList (tSippGlobPtr, argc, argv)
  151.     tSippGlob_pt    tSippGlobPtr;
  152.     int             argc;
  153.     char          **argv;
  154. {
  155.     bool  textures;
  156.     char *listPtr;
  157.  
  158.     if (argc == 3) {
  159.         if (!STREQU (argv [1], "-tex")) {
  160.             Tcl_AppendResult (tSippGlobPtr->interp,
  161.                               "expected option of `-tex', got `",
  162.                               argv [1], "'", (char *) NULL);
  163.             return FALSE;
  164.         }
  165.         textures = TRUE;
  166.         listPtr = argv [2];
  167.     } else {
  168.         textures = FALSE;
  169.         listPtr = argv [1];
  170.     }
  171.     return PushVertexList (tSippGlobPtr, textures, listPtr);
  172.  
  173. } /* PushVertexArgList */
  174.  
  175. /*=============================================================================
  176.  * SippVertexPush --
  177.  *   Implements the command:
  178.  *      SippVertexPush [-tex] vertexList
  179.  * Note:
  180.  *   This procedure has standard Tcl command calling sematics.  ClientData
  181.  * contains a pointer to the Tcl SIPP global structure.
  182.  *-----------------------------------------------------------------------------
  183.  */
  184. static int
  185. SippVertexPush (clientData, interp, argc, argv)
  186.     char       *clientData;
  187.     Tcl_Interp *interp;
  188.     int         argc;
  189.     char      **argv;
  190. {
  191.     if ((argc < 2) || (argc > 3)) {
  192.         Tcl_AppendResult (interp, "wrong # args: ", argv [0],
  193.                           " [-tex] vertexList", (char *) NULL);
  194.         return TCL_ERROR;
  195.     }
  196.     if (PushVertexArgList ((tSippGlob_pt) clientData, argc, argv))
  197.         return TCL_OK;
  198.     else
  199.         return TCL_ERROR;
  200.  
  201. } /* SippVertexPush */
  202.  
  203. /*=============================================================================
  204.  * SippPolygonPush --
  205.  *   Implements the command:
  206.  *       SippPolygonPush [[-tex] vertexList]
  207.  * Note:
  208.  *   This procedure has standard Tcl command calling sematics.  ClientData
  209.  * contains a pointer to the Tcl SIPP global structure.
  210.  *-----------------------------------------------------------------------------
  211.  */
  212. static int
  213. SippPolygonPush (clientData, interp, argc, argv)
  214.     char       *clientData;
  215.     Tcl_Interp *interp;
  216.     int         argc;
  217.     char      **argv;
  218. {
  219.     bool  textures;
  220.  
  221.     if (argc > 3) {
  222.         Tcl_AppendResult (interp, "wrong # args: ", argv [0],
  223.                           " [[-tex] vertexList]", (char *) NULL);
  224.         return TCL_ERROR;
  225.     }
  226.     if (argc > 1) {
  227.         if (!PushVertexArgList ((tSippGlob_pt) clientData, argc, argv))
  228.             return TCL_ERROR;
  229.     }
  230.  
  231.     polygon_push ();
  232.     return TCL_OK;
  233.  
  234. } /* SippPolygonPush */
  235.  
  236. /*=============================================================================
  237.  * SippSurfaceCreate --
  238.  *   Implements the command:
  239.  *     SippSurfaceCreate shaderhandle
  240.  * Note:
  241.  *   This procedure has standard Tcl command calling sematics.  ClientData
  242.  * contains a pointer to the Tcl SIPP global structure.
  243.  *-----------------------------------------------------------------------------
  244.  */
  245. static int
  246. SippSurfaceCreate (clientData, interp, argc, argv)
  247.     char       *clientData;
  248.     Tcl_Interp *interp;
  249.     int         argc;
  250.     char      **argv;
  251. {
  252.     tSippGlob_pt    tSippGlobPtr = (tSippGlob_pt) clientData;
  253.     Surface        *surfacePtr;
  254.     Shader         *shaderPtr;
  255.     void           *surfDescPtr;
  256.  
  257.     if (argc != 2) {
  258.         Tcl_AppendResult (interp, "wrong # args: ", argv [0], "  shaderhandle",
  259.                           (char *) NULL);
  260.         return TCL_ERROR;
  261.     }                     
  262.  
  263.     shaderPtr = TSippShaderHandleToPtr (tSippGlobPtr, argv [1],
  264.                                         &surfDescPtr);
  265.     if (shaderPtr == NULL)
  266.         return TCL_ERROR;
  267.  
  268.     surfacePtr = surface_create (surfDescPtr, shaderPtr);
  269.     if (surfacePtr == NULL) {
  270.         Tcl_AppendResult (interp, "the polygon stack is empty",
  271.                          (char *) NULL);
  272.         return TCL_ERROR;
  273.     }
  274.  
  275.     BindSurfaceToHandle (tSippGlobPtr, surfacePtr);
  276.     return TCL_OK;
  277.  
  278. } /* SippSurfaceCreate */
  279.  
  280. /*=============================================================================
  281.  * SippSurfaceDelete --
  282.  *   Implements the command:
  283.  *     SippSurfaceDelete surfacelist
  284.  * Note:
  285.  *   This procedure has standard Tcl command calling sematics.  ClientData
  286.  * contains a pointer to the Tcl SIPP global structure.
  287.  *-----------------------------------------------------------------------------
  288.  */
  289. static int
  290. SippSurfaceDelete (clientData, interp, argc, argv)
  291.     char       *clientData;
  292.     Tcl_Interp *interp;
  293.     int         argc;
  294.     char      **argv;
  295. {
  296.     tSippGlob_pt    tSippGlobPtr = (tSippGlob_pt) clientData;
  297.     int             idx;
  298.     handleList_t    surfaceList;
  299.     handleList_t    surfaceEntryList;
  300.  
  301.     if (argc != 2) {
  302.         Tcl_AppendResult (interp, "wrong # args: ", argv [0],
  303.                           " surfacelist", (char *) NULL);
  304.         return TCL_ERROR;
  305.     }                     
  306.     if (!TSippHandleListConvert (tSippGlobPtr, tSippGlobPtr->surfaceTblPtr,
  307.                                  argv [1], &surfaceList, &surfaceEntryList))
  308.         return TCL_ERROR;
  309.  
  310.     for (idx = 0; idx < surfaceList.len; idx++) {
  311.         Surface * surfacePtr = (surfaceList.ptr [idx]);
  312.  
  313.         surfacePtr->ref_count--;
  314.         Tcl_HandleFree (tSippGlobPtr->surfaceTblPtr, 
  315.                         surfaceEntryList.ptr [idx]);
  316.     }
  317.  
  318.     TSippHandleListFree (&surfaceList);
  319.     TSippHandleListFree (&surfaceEntryList);
  320.     return TCL_OK;
  321.  
  322. } /* SippSurfaceDelete */
  323.  
  324. /*=============================================================================
  325.  * SippSurfaceSetShader --
  326.  *   Implements the command:
  327.  *     SippSurfaceSetShader surfacelist shaderhandle
  328.  * Note:
  329.  *   This procedure has standard Tcl command calling sematics.  ClientData
  330.  * contains a pointer to the Tcl SIPP global structure.
  331.  *-----------------------------------------------------------------------------
  332.  */
  333. static int
  334. SippSurfaceSetShader (clientData, interp, argc, argv)
  335.     char       *clientData;
  336.     Tcl_Interp *interp;
  337.     int         argc;
  338.     char      **argv;
  339. {
  340.     tSippGlob_pt    tSippGlobPtr = (tSippGlob_pt) clientData;
  341.     int             idx;
  342.     handleList_t    surfaceList;
  343.     Shader         *shaderPtr;
  344.     void           *surfDescPtr;
  345.  
  346.     if (argc != 3) {
  347.         Tcl_AppendResult (interp, "wrong # args: ", argv [0],
  348.                           "  surfacelist shaderhandle", (char *) NULL);
  349.         return TCL_ERROR;
  350.     }                     
  351.  
  352.     if (!TSippHandleListConvert (tSippGlobPtr, tSippGlobPtr->surfaceTblPtr,
  353.                                  argv [1], &surfaceList, NULL))
  354.         return TCL_ERROR;
  355.  
  356.     shaderPtr = TSippShaderHandleToPtr (tSippGlobPtr, argv [2], &surfDescPtr);
  357.     if (shaderPtr == NULL)
  358.         goto errorExit;
  359.  
  360.     for (idx = 0; idx < surfaceList.len; idx++)
  361.         surface_set_shader ((Surface *) surfaceList.ptr [idx], surfDescPtr,
  362.                             shaderPtr);
  363.  
  364.     TSippHandleListFree (&surfaceList);
  365.     return TCL_OK;
  366. errorExit:
  367.     TSippHandleListFree (&surfaceList);
  368.     return TCL_ERROR;
  369.  
  370. } /* SippSurfaceSetShader */
  371.  
  372. /*=============================================================================
  373.  * TSippPolyInit --
  374.  *   Initialized the polygon and surface commands, including creating the 
  375.  *   polygon table.
  376.  *
  377.  * Parameters:
  378.  *   o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
  379.  *-----------------------------------------------------------------------------
  380.  */
  381. void
  382. TSippPolyInit (tSippGlobPtr)
  383.     tSippGlob_pt  tSippGlobPtr;
  384. {
  385.     static tSippTclCmdTbl_t cmdTable [] = {
  386.         {"SippVertexPush",       SippVertexPush},
  387.         {"SippPolygonPush",      SippPolygonPush},
  388.         {"SippSurfaceCreate",    SippSurfaceCreate},
  389.         {"SippSurfaceDelete",    SippSurfaceDelete},
  390.         {"SippSurfaceSetShader", SippSurfaceSetShader},
  391.         {NULL,                NULL}
  392.     };
  393.  
  394.     tSippGlobPtr->surfaceTblPtr = 
  395.         Tcl_HandleTblInit ("surface", sizeof (Surface *), 24);
  396.  
  397.     TSippInitCmds (tSippGlobPtr, cmdTable);
  398.  
  399. } /* TSippPolyInit */
  400.  
  401.